package com.strive.security;

import com.strive.entity.SysUser;
import com.strive.service.SysUserService;
import com.strive.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @description： 继承底层的用户认证类 重写接口实现用户认证的查库方法
 * @author：StrivePeng
 */
@Service
public class UserDetailServiceImpl implements UserDetailsService {

    // 引入Userservice
    @Autowired
    SysUserService sysUserService;


    /**
     * 获取用户信息
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 通过用户名获取用户信息（查库操作）
        SysUser sysUser = sysUserService.getByUsername(username);
        // 判空
        if (sysUser == null) {
            // 如果为空 返回异常信息
            throw new UsernameNotFoundException("用户名或密码错误");
        }

        // 如果存在 直接返回userdetail的一个封装类 使用了自定义的user类，重写了AccountUser类
        return new AccountUser(sysUser.getId(), sysUser.getUsername(), sysUser.getPassword(), getUserAuthority(sysUser.getId()));
    }

    /**
     * 自定义一个方法 返回用户权限信息
     * 包括：用户的角色信息以及菜单权限信息
     */
    public List<GrantedAuthority> getUserAuthority(Long userId) {

        // 角色 需要在前面加前缀(ROLE_admin)、菜单操作权限 直接用权限编码(sys:user:list)
        // 返回的信息格式如下： ROLE_admin, sys:user:list, ......
        String authority = sysUserService.getUserAuthorityInfo(userId);

        /**
         * 通过一个工具进行权限的转载 按照，隔开的方式进行转义
         * 通过工具自动封装成 需要的格式
         */
        return AuthorityUtils.commaSeparatedStringToAuthorityList(authority);
    }
}
